package auth

import (
	"context"
	"encoding/json"
	"errors"
	"fmt"
	"github.com/gin-gonic/gin"
	"github.com/go-redis/redis/v8"
	"meituan/apps/admin/models"
)

// 用户登陆验证逻辑
type Subject struct {
	ISLogin bool
	Realm   Realm
	Info    AuthInfo
}

// NewSubject 实例化Subject
func NewSubject(realm Realm) *Subject {
	return &Subject{
		ISLogin: false,
		Realm:   realm,
	}
}

// FromContext 从Context中获取Subject
func FromContext(realm Realm, ctx *gin.Context) (*Subject, error) {
	token := ctx.GetHeader("auth")
	if len(token) == 0 {
		return nil, AuthError{
			Message: "用户未登录",
		}
	}
	fmt.Printf("%s", token)
	// 从redis中获取认证信息
	conn := redis.NewClient(&redis.Options{
		Addr: "localhost:6379",
	})
	defer conn.Close()
	res := conn.Keys(context.Background(), fmt.Sprintf("*%s", token)).String()

	if len(res) != 0 {
		info := new(DefaultAuthInfo)
		_ = json.Unmarshal([]byte(res), info)
		return &Subject{
			ISLogin: true,
			Realm:   realm,
			Info:    info,
		}, nil
	}
	return nil, errors.New("no login")
}

// Login 登陆
func (subject *Subject) Login(user *models.Users) (info AuthInfo, err error) {
	info, err = subject.Realm.AuthenticationInfo(user)
	if err == nil {
		subject.Info = info
		subject.Info.SaveDB(12000)
	}

	return
}

// HasResource 是否拥有资源访问权限
func (subject *Subject) HasResource(user *models.Users) (err error) {
	err = subject.Realm.HasPermission(subject.Info)
	return
}

// HasRole 是否拥有角色
func (subject *Subject) HasRole(user *models.Users) (err error) {
	err = subject.Realm.HasPermission(subject.Info)
	return
}

// HasPerm 是否拥有权限
func (subject *Subject) HasPerm(user *models.Users) (err error) {
	err = subject.Realm.HasPermission(subject.Info)
	return

}
